import {BlockhashWithExpiryBlockHeight, Connection} from '@solana/web3.js';
import {
  createContext,
  ReactNode,
  useContext,
  useEffect,
  useMemo,
  useState,
} from 'react';
import Config from 'react-native-config';

type SolanaClientContextType = {
  solanaClient: Connection | undefined;
  chainId: string;
  setSolanaClient: (value: Connection | undefined) => void;
  switchChain: (value: string) => void;
  getRecentBlockhash: () => Promise<BlockhashWithExpiryBlockHeight>;
};

export const SolanaClientContext = createContext<
  SolanaClientContextType | undefined
>(undefined);

export const useSolanaClientProvider = () => {
  const context = useContext(SolanaClientContext);
  if (!context) {
    throw new Error(
      'useSolanaClientProvider must be used within an SolanaClientProvider',
    );
  }
  return context;
};

export function SolanaClientProvider({
  children,
}: Readonly<{
  children: ReactNode;
}>) {
  const [chainId, setChainId] = useState<string>(
    Config.APP_MODE != 'prod' ? 'solana-devnet' : 'solana-mainnet',
  );
  const [solanaClient, setSolanaClient] = useState<Connection>();

  const switchChain = (value: string) => {
    setChainId(value);
  };

  const getRecentBlockhash = async () => {
    return await solanaClient!.getLatestBlockhash('confirmed');
  };

  useEffect(() => {
    if (chainId == 'solana-mainnet') {
      const connection: Connection = new Connection(Config.SOLANA_MAINNET_RPC);
      setSolanaClient(connection);
    } else {
      console.log('Config.SOLANA_DEVNET_RPC', Config.SOLANA_DEVNET_RPC);
      const connection: Connection = new Connection(Config.SOLANA_DEVNET_RPC);
      setSolanaClient(connection);
    }
  }, [chainId, setChainId]);

  const value = useMemo(
    () => ({
      solanaClient,
      chainId,
      setSolanaClient,
      switchChain,
      getRecentBlockhash,
    }),
    [solanaClient, chainId],
  );

  return (
    <SolanaClientContext.Provider value={value}>
      {children}
    </SolanaClientContext.Provider>
  );
}
